package ch.bfh.mobicomp.soda2.gps_datacollector.business.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import android.os.Environment;
import android.text.format.Time;
import android.util.Log;

public class SODA_GPS_DataFileWriter {

    private static final String TAG = SODA_GPS_DataFileWriter.class.getName();
    private static final String NEWLINE = System.getProperty("line.separator");
    private static final String PATH = Environment.getExternalStorageDirectory() + "/DropyBoxy/";
    private static final int MAX_LINECOUNT = 30;

    private boolean externalStorageisWritable;
    private File directory;
    private File file;
    private int lineCount;
    private Time time;
    private FileOutputStream fileOutputStream;
    private OutputStreamWriter outputStreamWriter;
    private Writer writer;

    public SODA_GPS_DataFileWriter() {
        lineCount = 0;
        time = new Time();
        externalStorageisWritable = isExternalStorageWritable();
        if (externalStorageisWritable) {
            directory = getDropBoxDirectory();
        }
    }

    /* Checks if external storage is available for read and write */
    private boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            Log.d(TAG, "Externanl Storage is Mounted");
            return true;
        }
        Log.e(TAG, "External Storage is not mounted");
        return false;
    }

    private File getDropBoxDirectory() {
        File dbdirectory = new File(PATH);
        if (dbdirectory.isDirectory()) {
            Log.d(TAG, "DropBoxdirectory found: " + dbdirectory.getAbsolutePath());
            return dbdirectory;
        }
        if (dbdirectory.mkdir()) {
            return dbdirectory;
        }
        Log.e(TAG, "DropBoxdirectory not found, returning Null: "+dbdirectory);
        return null;
    }

    private void writeTableDataRow(Writer myWriter, String timestamp, String latitude, String longitude, String altitude) {
        String line = timestamp+";"+latitude+";"+longitude+";"+altitude+ NEWLINE;
        writeLine(myWriter, line);
    }

    private void writeTableHeader(Writer myWriter) {
        String line = "Time;Latitude;Longitude;Altitude"+NEWLINE;
        writeLine(myWriter, line);
    }

    private void writeLine(Writer writer, String line){
        try{
            writer.append(line + lineCount);
            writer.flush();
            Log.d(TAG, "Write TableLine: "+ line);
        } catch (IOException e) {
            Log.e(TAG, "Writing TableLine failed");
        }
        
    }
    
    private Writer createWriter(File myfile) {
        try {
            fileOutputStream = new FileOutputStream(myfile);
            outputStreamWriter = new OutputStreamWriter(fileOutputStream);
        } catch (FileNotFoundException e) {
            Log.e(TAG, "Create Writer Failed");
        }
        Log.d(TAG, "Returning writer");
        return new BufferedWriter(outputStreamWriter);
    }

    public void writetoFile(String timestamp, String latitude, String longitude, String altitude) {
        if (externalStorageisWritable && directory != null) {
            if (externalStorageisWritable) {
                if (lineCount == 0) {
                    time.setToNow();
                    String filename = "GPS_DATA_" + time.format2445() + ".csv";
                    file = new File(directory, filename);
                    Log.d(TAG, "Created new File: " + file.getAbsolutePath());
                    writer = createWriter(file);
                    writeTableHeader(writer);
                    writeTableDataRow(writer, timestamp, latitude, longitude, altitude);
                } else {
                    writeTableDataRow(writer, timestamp, latitude, longitude, altitude);
                }
                lineCount++;
                Log.d(TAG, "increased Linecount: " + lineCount);
                if (lineCount >= MAX_LINECOUNT) {
                    lineCount = 0;
                    try {
                        writer.close();
                    } catch (IOException e) {
                        Log.e(TAG, "Writer closing failed");
                    }
                }
            }

        }

    }

    public void closeWriter(){
        try {
            writer.close();
            Log.d(TAG, "Writer closed");
        } catch (Exception e) {
            Log.e(TAG, "Closing Writer failed");
        }
    }
}
